Copyright: TVCLUnZip Copyright 1997, Kevin L. Boylan


Contents
The TVCLUnZip Component

 Properties    Events   Methods             Installing   Registering

What is it?

The VCLUnZip Delphi component allows you to add UNZIP capabilites to your application. This component is different from other "UNZIP" development libraries in that it is written in 100% Delphi Object Pascal code and is full featured.  There are no DLL's to tote around.  This component links right into your application's executable. It is very easy to use.  It works with both Delphi 1 (16 bit) and Delphi 2 (32 bit).  Both versions support long filenames completely.  Even the 16 bit version will unzip files with long filenames and long directory names.  Also supported are disk spanning and encryption.  Registering will also get you all source code.

** Please test the component out completely to your satisfaction before registering to be sure that it meets your requirements.  I do not guarantee that it is completely free from bugs.  This component has been tested, but not under all conditions yet.

The unzipping algorithm is based on  public domain software called INFOZIP.  This is the same code that most if not all other DLL zip/unzip components are based on.  There is no C code in this component ofcourse. It is a complete translation of the INFLATE, EXPLODE, UNREDUCE, and UNSHRINK modules and a complete rewrite of the rest into Delphi Object Pascal.  I would like to thank Mark Adler and the rest of the INFOZIP group for making their code publicly available.

Included in this zip file is a fully functional component. Also included in this zip file is the COMPLETE SET OF SOURCE CODE.  When you register you will receive the necessary passwords to extract the source code.  There is also a fairly complete unzip application which is useful as an example of how to use the component.  With the example you can open and view zip files, extract files from zip files, and even view files from within the zip files by double-clicking on any compressed file.

This is the first release for this component so please let me know of any bugs that you might find.  I have plans for enhancements and I also have plans (infact I'm already working on it, BUT NO PROMISES ON WHEN AND IF IT WILL BE AVAILABLE) for a TVCLZip component. The TVCLZip component will descend from the TVCLUnZip component and so will have both ZIP and UNZIP capabilites.  When the TVCLZip component is available you will be able to upgrade to it for only the diffence in price.

Price

TVCLUnZip              $15 - SWREG 15187

TVCLZip                   $unknown - depends on interest and feedback as to how much support would be considered necessary. I'm guessing $30-$40 at this point

When you register this component, I will email to you the necessary password that will allow you to extract all source code from this zip file.  You will then be able to re-install the component using this source code which will remove the nag message window that is shown by the demo component whenever a zip files is opened. You will also be put on a mailing list so that I can notify you of any upgrades or bug fixes.

Pricing and Support Philosophy

I am keeping the price very low so as to make zip capabilites available to developers that can't afford the almost $200 price tags of most ZIP libraries on the market today.

Email support is available.  I will do my best to fix any bugs that are found AND to add any enhancements that you think would make this component more productive.  I can't provide a 'round the clock' help desk support but I will do the best I can.

Future enhancements

Some of the things on the list that I hope to add in the sometime in the future:

1. Stream compression.

2. Memory mapped files for WIN32.

3. Threaded decompression.

4. Added and improved events.

5. Installation program.

6. Continual enhancement to documentation and capabilities.

Contact

Please feel free to test this component thoroughly before registering.  I'll be glad to answer any questions you might have, just email me at

boylank@compuserve.com


Installation
Installing TVCLUnZip and it's HELP file

Within the VCLUnZip.zip file you will find separate zip files.

UZCOMP16.ZIP & UZCOMP32.ZIP

You should unzip these files into the directory to which you normally install new components.  In my environment for 32 bit this directory is

c:\Program Files\Borland\Delphi 2.0\Components

Whatever directory you use should appear in or be added to the the Component|Install dialog box in the Search Paths edit field.

Within the 32 bit (UZCOMP32.ZIP) there is

VCLUNZIP.DCU   (Compiled unit)

VCLUNZIP.DCR   (Resource file)

Within the 16 bit (UZCOMP16.ZIP) there is

VCLUNZIP.DCU  (Compiled unit)

VCLUNZIP.DCR  (Resource file)

 UZSOURCE.ZIP

When you have registered and received the correct password, you should unzip these files to the same directory as the TVCLUnZip.DCU (See above). They are not necessary to use the component however and you can just skip these files until  you have registered.  A password will be required, which you will receive when you register, in order to unzip these files.

 LIBRARY.ZIP

You may unzip these to the same directory that you extracted the COMPS.ZIP files to if you wish, but since they are not components, I prefer to unzip them to a separate library directory.  In my environment that is

C:\Program Files\Borland\Delphi 2.0\Library

Whatever directory you use should appear in or be added to the the  Project|Options Directories/Conditionals dialog box Search Path.

Within LIBRARY.ZIP you will find:

TCONTAIN.PAS	Required for Delphi 1 and 2. A container utility

KPLIB.PAS	Required for Delphi 1 and 2. Several utility procedures

MATCH.PAS	Required for Delphi 1 and 2. Used to match wildcard patterns to filenames

**>> The following two files only need to be installed for Delphi 1

CALL32NT.PAS	Used to implement long filenames in 16 bit Delphi.  Only needed for Delphi 1

LONGNAME.PAS	Used to implement long filenames in 16 bit Delphi.  Only needed for Delphi 1

EXAMPLE.ZIP

This is the example unzip application.  Please see the EXAMPLE.TXT file for instructions on properly extracting these files.

Install the VCLUnZip.DCU file using the Component|Install dialog box. It will be added to the SAMPLES palatte.  If you have registered, install the VCLUnZip.PAS file instead.

Installing the Component's Help

Move the VCLZIP.HLP file from your component directory to your DELPHI\BIN directory.  Move the VCLZIP.KWF file to your DELPHI\HELP directory.  Now run the HELPINST.EXE (either double click from File Manager in the HELP directory or from the icon in Program Manager.   Now, while in HELPINST, click the open file toolbar button and find and select the DELPHI.HDX file in the DELPHI\BIN directory.  Then click the '+' toolbar button and find and select the VCLZIP.KWF file in the DELPHI\HELP directory.  This will add the VCLZIP.KWF file to the listbox that you can see.  Now click the 'Save' toolbar button and the VCLZIP help file will be registered with Delphi.  You may now exit.

Installing the HELP files in this way will allow you to get context sensitive help on each property and event by pressing F1 while a particular property or event is selected in the Object Inspector.


Getting Started

Basic procedure for programming the TVCLUnZip component:

If you simply wish to extract all files from a particular zip file it is as easy as just specifying the ZipName and DestDir properties and then call the UnZip method.  That's it.  If you wish to do more, the following pseudo example gives a very cursory overview of the kinds of  things you can do...

FileList: TStringList;

MemoPad: TMemo;

Unzipper: TVCLUnZip;

NumUnzipped: Integer;

With Unzipper do

begin

ZipName := 'Zipfile.zip'    // set the zip filename

ReadZip;                           // open it and read its information

// List filenames in zip file

for i := 0 to Count-1 do

MemoPad.Lines.Add( Filename[i] + #9 + Pathname[i] );

// extract some files

// determine which files to unzip

FileList.Add( '*.cpp' );              // unzip all .cpp files

FileList.Add( 'myprog.exe' );   // unzip myprog.exe

FileList.Add( '?[0-9]*\*.h' );      // .h files, if 2nd letter of dir starts with digit only

FileList.Add( Filename[FCount-1] );   // extract last entry in zipfile

DoAll := False;                  // Don't unzip all files

DestDir := 'c:\mydir'         // Set destination directory

RecreateDirs := False;     // don't recreate directory structures

NumUnzipped := Unzip;                        // Extract files

end;


Long Filenames

Long Filenames are supported under both Delphi 1 and Delphi 2.

WIN95

Both the Delphi 1 and Delphi 2 versions will completely support long filenames, even if long filenames are fed to the component as ZipName and DestDir.  The Delphi 1 version will create directories and files with their complete long filename.

WIN31

You may unzip files from a zip file even if the internal filename and or pathname is a long filename. The filename will be appropriately shortened.  It is possible to end up with two different long filenames shortened to the same name, however  A hashing function based on the file's complete name is used to append a character that attempts to make the shortened filename unique.


ReadZip

procedure ReadZip;

Causes the zip file to be opened and all pertinant information to be read from the zip file.  The information on each file can be accessed by the indexed properties described later.  You should call this procedure after setting the ZipName property. This procedure only needs to be called if you plan to access the files information such as Filename[Index].  You can call the UnZip function without calling ReadZip first.


UnZip

function UnZip: Integer;

Causes the files defined in FilesList property to be extracted.  If FilesList is empty then all files in the zip file are extracted.  The return value is the number of files successfully unzipped.


Properties
TVCLUnZip Properties

Public Properties

Indexed Properties

Filename

Pathname

FullName

CompressMethod

CompressMethodStr

DateTime

Crc

CompressedSize

UnCompressedSize

IsEncrypted

FileHasComment

FileComment

DiskNo

Zip File Properties

Count

ZipHasComment

ZipComment

Password

Published Properties

ZipName

DestDir

SortMode

RecreateDirs

OverwriteMode

FilesList

DoAll


ClearZip

procedure ClearZip;

Removes all of the zip information from memory.  The component is still ready to open another zipfile.  Opening another zipfile will take care of this for you so this is usually optional.


FillList

procedure FillList( FilesList: TStrings );

Fills the string list with tab delimited information on each file.  Useful if you want to display information on all files in a listbox.  It is usually best to just used the indexed properties so that you can fill the fileslist the way you want.


Sort

procedure Sort( SMode: TZipSortMode );

Sorts the zip information according to SortMode.  The default sort mode is ByNone.

WARNING

If you are working with a multi-part zip file, it is most efficient to have the zip information sorted with SortMode = ByNone.  If you have the information sorted by any other mode and you are working with a mulit-part file, the component will have to sort the information using the ByNone mode and then sort the information back to the way you had it sorted.   This will only be noticable on zip files containing a large number of entries.


Count

property Count: Integer;

Returns the number of files in the Zip file.


Filename

property Filename[Index: Integer]: TZipFilename;

Returns just the filename portion of the file, without the path. TZipFilename type is just a String type.


Pathname

property Pathname[Index: Integer]: TZipPathname;

Returns just the pathname portion of the file, without the filename.


FullName

property FullName[Index: Integer]: String;

Returns the full path and filename of the file.  Same as  Pathname[x] + Filename[x].


CompressMethod

property CompressMethod[Index: Integer]: WORD;

Returns the compression method of the particular file.

Return value:

STORED =       0;

SHRUNK =       1;

REDUCED1 =   2;

REDUCED2 =   3;

REDUCED3 =   4;

REDUCED4 =   5;

IMPLODED =    6;

TOKENIZED =   7;

DEFLATED =    8;


CompressMethodStr

property CompressMethodStr[Index: Integer]: String;

Returns a string representation of the compression method for the particular file. The strings returned will be one of the following:

STORED =	'STOR'

SHRUNK =	'SHR'

REDUCED1 =	'RED1'

REDUCED2 =	'RED2'

REDUCED3 =	'RED3'

REDUCED4 =	'RED4'

IMPLODED =	'IMP'

TOKENIZED =	'TOK'

DEFLATED =	'DEF'


DateTime

property DateTime[Index: Integer]: TDateTime;

Returns the Date and Time stamp for the particular file in TDateTime format.


Crc

property Crc[Index: Integer]: LongInt;

Returns the CRC for the particular file that is stored in the zipfile.


CompressedSize

property CompressedSize[Index: Integer]: LongInt;

Returns the compressed size of the file.


UnCompressedSize

property UnCompressedSize[Index: Integer]: LongInt;

Returns the uncompressed size of the file.


IsEncrypted

property IsEncrypted[Index: Integer]: Boolean;

Returns True if the compressed file is encrypted.


FileHasComment

property FileHasComment[Index: Integer]: Boolean;

Returns True if the particular file has a comment.


FileComment

property FileComment[Index: Integer]: String;

Returns the comment for the specified file, if there is one. For 16 bit (Delphi 1) no more than 255 characters of the comment are returned.


DiskNo

property DiskNo[Index: Integer]: Integer;

Returns the disk number of the specified file.  This is useful when working with multi-file zip files (DISK SPANNING).  For single file zip files this will always return a 1, but for multi-file zip files it will return the actual disk that the compressed file begins on.


ZipHasComment

property ZipHasComment: Boolean;

Returns True if the zipfile itself has a comment.


ZipComment

property ZipComment: String;

Returns the zipfile's comment if there is one.  For 16 bit (Delphi 1) no more than 255 characters of the comment are returned.


Password

property Password: String;

If set, this password will be used when uncompressing encryped files.


ZipName

property ZipName: String;

The path and name of the zipfile.  This must, ofcourse, be set before you can do anything with or get information from the zipfile.  After setting the ZipName you should call ReadZip to cause the zipfile's information to be read (Calling ReadZip is optional if you do not plan to access the Indexed Properties before unzipping files.  Calling UnZip will cause ReadZip to be called if it hasn't already been called).

Setting ZipName to a '?' will cause a fileopen dialogbox to be displayed so that a file can be selected.  If you set ZipName to '?' and the user presses the cancel button on the FileOpen dialog box, a EUserCanceled exception will be thrown and ZipName, along with all other properties will remain unchanged.


DestDir

property DestDir: String;

This is the path to where files will be extracted. If it does not exist it will be created even if several levels of directories must be created.  In other words if DestDir is set to c:\dir1\dir2\dir3 and only c:\dir1 exists, dir2 and dir3 will be created.  It does not matter whether you include a '\' at the end.

If DestDir is set to a '?' then a directory finder dialog box will be displayed so that a directory can be selected. If you set DestDir to '?' and the user presses the cancel button on the dialog box, a EUserCanceled exception will be thrown and DestDir, along with all other properties will remain unchanged


SortMode

property SortMode: TZipSortMode;

Set this property to determine what order the information from the zipfile will be in when it is read.  In order to re-sort the information if it has already been read in, call the Sort method.

TZipSortMode = (ByName, ByFileName, ByDirectoryName, ByDate, ByCompressedSize, ByUnCompressedSize, ByRate, ByNone);


RecreateDirs

property RecreateDirs: Boolean;

Set this property to True if you want to use directory information in the zipfile when extracting files.  The directories will be created relative to the DestDir (Destination Directory).  If this property is False, all files will be extracted to the DestDir, which could possibly result in files of the same name overwriting each other if the OverwriteMode property is set to Always.


OverwriteMode

property OverwriteMode: TUZOverwriteMode;

Set OverwriteMode to determine what should be done if a file is about to be extracted and a file of the same name already exists in the destination directory.  The possible modes are

TUZOverwriteMode = (Prompt, Always, Never);   ( The default is Prompt )

If set to Prompt, one of two things will happen.  If the OnPromptForOverwrite event is defined then it will be called and the application can decide whether to overwrite the file.  If the OnPromptForOverwrite event is NOT defined then the component will display a messagebox to allow the user to decide whether to overwrite the file.

If set to Always, the file will be overwritten.  If set to Never, the file will not be extracted if it would overwrite a file.


FilesList

property FilesList: TStringList;

Add filenames and/or wildcard specifications to this file list to specify what files will be extracted from the zipfile.  If the property DoAll is set to True then the contents of this list will be ignored and all files will be extracted.  Also, if FilesList is empty all files will be extracted, even if DoALL is not set to True.


DoAll

property DoAll: Boolean;

If set to True then all files in the zipfile will be extracted when the UnZip method is called.


OnStartUnzipInfo

TStartUnzipInfo = procedure( Sender: TObject; NumFiles: Integer; TotalBytes: LongInt; var StopNow: Boolean ) of Object;

Triggered just before the first file is to be extracted, giving you a chance to abort. NumFiles is the total number of files that is about to be extracted.  TotalBytes is the total number of uncompressed bytes that make up those files.  Set StopNow to True if you do not wish continue to have the files unzipped.


OnStartUnZip

TStartUnZipEvent = procedure( Sender: TObject; FileIndex: Integer; FName: String ) of Object;

Triggered just before a file is about to be extracted.  FName is the complete path and filename of the file that is about to be unzipped.


OnFilePercentDone

TFilePercentDone = procedure( Sender: TObject; Percent: LongInt ) of Object;

Triggered periodically to report the progress on the current file being extracted.  Percent represents a percentage between 1 and 100.


OnTotalPercentDone

TTotalPercentDone = procedure( Sender: TObject; Percent: LongInt ) of Object;

Triggered periodically to report the progress of the total bytes of all the files that are being extracted.  Percent represents a percentage between 1 and 100.


OnEndUnZip

TEndUnZipEvent = procedure( Sender: TObject; FileIndex: Integer ) of Object;

Triggered just after each file has been extracted.


OnPromptForOverwrite

TPromptForOverwrite = procedure( Sender: TObject; var OverWriteIt: Boolean; FileIndex: Integer; var FName: String ) of Object;

Triggered when the property OverwriteMode is set to Prompt and a file is about to be overwritten.  This gives you a chance to determine whether to overwrite or not.  Set OverWriteIt to True if you wish to overwrite the file, otherwise the file will not be overwritten. You also have the opportunity to rename the file that is about to be unzipped.  If you do this, you should also set OverwriteIt to True.

If this event is not defined and the property OverwriteMode is set to Prompt then the TVCLUnZip control will display a messagebox to ask whether the file that is about to be overwritten, should be overwritten.  In this case you do not get a chance to rename the file.


OnSkippingFile

TSkippingFile = procedure( Sender: TObject; Reason: TSkipReason;  FileIndex: Integer ) of Object;

Triggered when a file that would have otherwise been extracted is being skipped. The reason for the file being skipped is in the Reason argument.  At this time the following reasons are defined.

TSkipReason = (srBadPassword, srNoOverwrite);

If an attempt is made to extract an encryped file and the Password property does not match the file's password, then the file will be skipped.  If a file is skipped because it would have been overwritten and either the OverWriteMode property was set to Never, or Prompt and the OnPromptForOverwrite event returned False for OverWriteIt, this event will be triggered.


OnBadPassword

TBadPassword = procedure( Sender: TObject; FileIndex: Integer ) of Object;

Triggered whenever an attempt is made to extract an encrypted file with an incorrect password.  The file will be skipped.


OnBadCRC

TBadCRC = procedure(Sender: TObject; CalcCRC, StoredCRC: LongInt; FileIndex: Integer ) of Object;

Triggered when the value for the CRC for a file just extractd does not match the CRC that was calculated by the TVCLUnZip component.  The file was still extracted, this is for informational purposes only.  The values for the calculated CRC and the stored CRC are passed in the CalcCRC and StoredCRC variables respectively.


OnInCompleteZip

TIncompleteZip = procedure(Sender: TObject; var IncompleteMode: TIncompleteZipMode ) of Object;

TIncompleteZipMode = (izAssumeMulti, izAssumeBad);

Triggered whenever the component cannot find an END CENTRAL DIRECTORY which means one of the following:

1. The file is not a zip file

2. The zip file is corrupted or truncated

3. This is part of a multi-file zipfile and it is not the last file/disk in the set.

This event passes the IncompleteMode as a modifiable argument.  If you want the component to treat the zip file as an incomplete/corrupted zip file then set IncompleteMode to izAssumeBad and the component will attempt to read as much of the zipfile as possible. If you want the file to be treated as a multi-part zip file set IncompleteMode to izAssumeMulti and the component will drop out and allow you the chance to insert the last disk of the set and try again.

Note that if this event is called, and TIncompleteZipMode is set to izAssumeMulti then the current disk is not the last disk in the multi-file disk set.  You will need to put the last disk of the set into the drive and call the component again.


OnGetNextDisk

TGetNextDisk = procedure(Sender: TObject; NextDisk: Integer ) of Object;

When working with a multi-part zip file this event is triggered when a file that is about to be unzipped is on a different disk from the one that is currently in the drive. NextDisk will tell you the disk number of the multi-part zipfile that should be inserted. The first disk in a disk set is number 1.

WARNING!  At this time there is no error checking to be sure the user inserted the correct disk.  Results of inserting the wrong disk are unknown and certainly bad.


Events
Basic Event Property Information

Most events return as a parmameter, the FileIndex of the file that is currently being operated on.  This FileIndex gives you access to all of that files information, for example Filename[FileIndex] is the filename of the file being processed.


Public Procedures
TVCLUnZip Methods

ReadZip

UnZip

ClearZip

FillList

Sort


Events
TVCLUnZip Events

OnStartUnzipInfo

OnStartUnZip

OnFilePercentDone

OnTotalPercentDone

OnEndUnZip

OnPromptForOverwrite

OnSkippingFile

OnBadPassword

OnBadCRC

OnInCompleteZip

OnGetNextDisk


Registering TVCLUnZip

The price for the TVCLUnZip component is $15 per developer.  There are no royalty fees.  You may not resell TVCLUnZip as an UnZip component nor may you use TVCLUnZip to create and sell a zip/unzip component.

Registering using SWREG# 15187 on Compuserve

You may register using SWREG on Compuserve (just GO SWREG) and enter the SWREG# 15187. My email account will receive notification almost immediately that you have registered at which time I will email the password to you, or at least as soon as I can read my mail.  I will know your email address from the registration information that I will receive.

Registering by Mail

Or you can send a check (made out to Kevin L. Boylan) to

Kevin L. Boylan

2333 Randy Drive

Kettering, OH 45440

Please be sure to include an email address so that I can send you the password, or if you prefer include a self addressed STAMPED envelope and I'll send it that way.

You will also receive instructions on how to install the component using the source code.

TVCLUnZip Delphi Componet - Copyright 1997, Kevin L. Boylan